package com.lianniu.web.pay.service.impl;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import com.alibaba.fastjson.JSON;
import com.lianniu.web.base.BaseResult;
import com.lianniu.web.buyerOrder.model.OrderInfoVo;
import com.lianniu.web.buyerOrder.service.IBuyerOrderService;
import com.lianniu.web.constants.ErrorCode;
import com.lianniu.web.pay.dao.YjfDao;
import com.lianniu.web.pay.model.PayRequestVo;
import com.lianniu.web.pay.model.YjfDealerVo;
import com.lianniu.web.pay.model.YjfNotifyLogVo;
import com.lianniu.web.pay.model.YjfSupplyVo;
import com.lianniu.web.pay.service.PayService;
import com.lianniu.web.pay.service.YjfService;
import com.lianniu.web.pay.util.PayConstants;
import com.lianniu.web.pay.util.YjfConstants;
import com.lianniu.web.pay.util.YjfProperty;
import com.lianniu.web.pay.util.YjfUtil;

@Service
public class YjfServiceImpl implements YjfService {

  private static Logger logger = LoggerFactory.getLogger(YjfServiceImpl.class);
  @Autowired
  private PayService payService;
  @Autowired
  private YjfDao yjfDao;
  @Autowired
  private IBuyerOrderService buyerOrderService;

  public BaseResult getRequestUrlAndStore(String userid, String service, Map<String, String> map) {
    Map<String, String> data = new TreeMap<String, String>();
    /** 加上公共请求头部 */
    data = initi(service, data);

    /** 获取外部传入的服务名 进入相应的业务参数处理方法 */

    if (YjfConstants.YJF_DEALER_REGISTER.equals(service)) {
      data = qftDealerRegister(userid, data,map);

    } else if (YjfConstants.YJF_SUPPLY_REGISTER.equals(service)) {
      data = qftSupplierApply(userid, data,map);

    } else if (YjfConstants.YJF_PAY.equals(service)) {
      data = qftIntegratedPayment(userid, data,map);

    } else if ("qftClear".equals(service)) {
      data = qftClear(userid, data);

    } else {

    }

    if("fail".equals(data.get("result"))){
      return BaseResult.fail(ErrorCode.ExceptionRetCode, data.get("msg"));
    }
    /** 加入签名 */
    data.put("sign", YjfUtil.encryption(YjfUtil.signString(data), YjfProperty.getSecuritycheckkey(),
        (map.get("signType") == "" || map.get("signType") == null) ? "MD5" : map.get("signType")));
    return BaseResult.success(YjfUtil.forLink(YjfProperty.getGatewayurl(), data));
  }



  /**
   * 
   * 初始化公共请求参数
   */

  private Map<String, String> initi(String service, Map<String, String> data) {

    data.put("partnerId", YjfProperty.getPartnerid());
    data.put("signType", YjfProperty.getSigntype());
    data.put("returnUrl", YjfProperty.getReturnurl());
    data.put("notifyUrl", YjfProperty.getNotifyurl());
    data.put("orderNo", (String) payService.getPayCode(service).getData());
    data.put("merchOrderNo", (String) payService.getPayCode("merchOrderNo").getData());

    return data;
  }

  /**
   * 企富通经销商开户
   * 
   * @param data
   * @return
   */
  private Map<String, String> qftDealerRegister(String userid, Map<String, String> data,
      Map<String, String> param) {
//    data.put("clientType", "PC");
    YjfDealerVo dealer = new YjfDealerVo();
    dealer.setUserid(userid);
    dealer.setUsername(param.get("username"));
    dealer.setMobile(param.get("mobile"));
    this.insertDealerRequest(dealer).getData();
    data.put("orderNo",dealer.getOrderNo());
    data.put("service",YjfConstants.YJF_DEALER_REGISTER);
    data.put("version", "1.0");
    data.put("registerUserType","PERSONAL");
    data.put("userName",param.get("username"));
    data.put("mobile",param.get("mobile"));
    
    return data;
  }

  /**
   * 企富通供应商申请
   * 
   * @param data
   * @return
   */
  private Map<String, String> qftSupplierApply(String userid, Map<String, String> data,
      Map<String,String> param) {
    YjfSupplyVo supply = new YjfSupplyVo();
    supply.setUserid(userid);
    this.insertSupplyRequest(supply);
    data.put("orderNo",supply.getOrderNo());
    data.put("termnalType", "MOBILE");
    data.put("outUserId",userid);
    data.put("registerUserType","ENTERPRISE");
    data.put("service",YjfConstants.YJF_SUPPLY_REGISTER);
    data.put("signType", "MD5");
    data.put("version", "1.0");

    return data;
  }

  /**
   * 企富通综合支付
   * 
   * @param data
   * @return
   */
  private Map<String, String> qftIntegratedPayment(String userid, Map<String, String> data, Map<String, String> map) {
    data.put("service", YjfConstants.YJF_PAY);

    YjfDealerVo dealer = (YjfDealerVo)this.getValidDealer(userid).getData();
    if(dealer == null){
      data.put("result","fail"); 
      data.put("msg", "用户还为注册易极付会员");
      return data;
    }
    /** 买家信息 */
    data.put("buyerUserId", dealer.getQft_userid());
    data.put("buyerRealName", dealer.getUsername());
    data.put("outUserId",dealer.getUserid());
    data.put("personalCorporateType", "PERSONAL");
    data.put("userTerminalType", "MOBILE");
    
    //构造commandPayOrders
    List<Map<String,String>> commandPayOrders = new ArrayList<Map<String,String>>();
    String[] orderids = map.get("orderid").split(",");
    for(String orderid : orderids){
      Map<String,String> payOrder =  new HashMap<String,String>();
      OrderInfoVo order = (OrderInfoVo)buyerOrderService.getOrderInfo(orderid).getData();
      String sellerUserid = order.getLstOrderDetail().get(0).getSupplyUserID();
      YjfSupplyVo supply = (YjfSupplyVo)this.getAuthenticatedSupply(sellerUserid).getData();
      if(supply == null){
        data.put("result","fail"); 
        data.put("msg", sellerUserid+"供应商还未注册为易极付支付用户");
        return data;
      }
      /** 卖家信息 */
      payOrder.put("merchOrderNo", order.getOrderCode());
      payOrder.put("sellerUserId", supply.getQft_userid());
      payOrder.put("tradeAmount",order.getPrice());
      payOrder.put("goodsName", "担保交易商品");
      
      commandPayOrders.add(payOrder);
    }
    
    data.put("commandPayOrders", JSON.toJSONString(commandPayOrders));

    PayRequestVo payRequest = (PayRequestVo)payService.payRequest(Arrays.asList(map.get("orderid").split(","))).getData();
    data.put("orderNo",payRequest.getPay_code());
    data.put("version", "1.0");

    return data;
  }
  
  public BaseResult getValidDealer(String userid){
    YjfDealerVo dealer = yjfDao.getValidDealer(userid);
    return BaseResult.success(dealer);
  }
  
  public BaseResult getAuthenticatedSupply(String userid){
    YjfSupplyVo supply = yjfDao.getAuthenticatedSupply(userid);
    return BaseResult.success(supply);
  }

  /**
   * 企富通清分
   * 
   * @param data
   * @return
   */
  private Map<String, String> qftClear(String userid, Map<String, String> data) {

    data.put("service", "qftClear");

    /** 商户自己定义一个清分的批次号， 结算的时候需要传入该批次号 */
    data.put("outBatchNo", "PR2016060313000163921243");

    /** outOrderNo为支付的时候的 outOrderNo payOrderNo为支付的时候返回的tradeNo */
    data.put("clearOrderItems",
        "[{\"outOrderNo\":\"80495706320014\",\"serviceCharge\":\"0.04\",\"payOrderNo\":\"200510FxtWwimw61819U\"},{\"outOrderNo\":\"80495621260010\",\"serviceCharge\":\"0.04\",\"payOrderNo\":\"200510FxtklGi061819i\"}]");
    data.put("version", "1.0");

    return data;
  }

  
  @Override
  public BaseResult insertDealerRequest(YjfDealerVo dealer) {
    dealer.setOrderNo((String)payService.getPayCode("userOrderNo").getData());
    dealer.setStatus(YjfConstants.DEALER_STATUS_1);
    yjfDao.insertDealerRequest(dealer);
    return BaseResult.success(dealer);
  }

  @Override
  public BaseResult insertSupplyRequest(YjfSupplyVo supply) {
    supply.setOrderNo((String)payService.getPayCode("supplyOrderNo").getData());
    supply.setStatus(YjfConstants.SUPPLY_STATUS_1);
    yjfDao.insertSupplyRequest(supply);
    return BaseResult.success(supply);
  }
  
  public BaseResult yjfNotify(Map<String,String> map){
    String service = map.get("service");
    
    if (YjfConstants.YJF_DEALER_REGISTER.equals(service)) {
      return qftDealerRegisterNotify(map);
    } else if (YjfConstants.YJF_SUPPLY_REGISTER.equals(service)) {
      return qftSupplierApplyNotify(map);
    } else if (YjfConstants.YJF_PAY.equals(service)) {
      return qftIntegratedPaymentNotify(map);
    }
    return BaseResult.success();
  }
  
  private BaseResult qftDealerRegisterNotify(Map<String,String> map){
    
    YjfDealerVo dealer = new YjfDealerVo();
    dealer.setQft_userid(map.get("userId"));
    dealer.setOrderNo(map.get("orderNo"));
    dealer.setStatus(YjfConstants.DEALER_STATUS_2);
    yjfDao.updateDealerRequest(dealer);
    return BaseResult.success();
  }
  
  private BaseResult qftSupplierApplyNotify(Map<String,String> map){
    YjfSupplyVo supply = new YjfSupplyVo();
    supply.setOrderNo(map.get("orderNo"));
    supply.setRegisterUserType(map.get("registerUserType"));
    supply.setQft_userid(map.get("userId"));
    supply.setStatus(YjfConstants.SUPPLY_STATUS_4);
    
    yjfDao.updateSupplyRequest(supply);
    return BaseResult.success();
  }
  
  @Transactional(value = "transactionManager", isolation = Isolation.DEFAULT,
      propagation = Propagation.REQUIRED, rollbackFor = {Exception.class})
  private BaseResult qftIntegratedPaymentNotify(Map<String,String> map){
    
    logger.info("支付回调service开始");
    logger.info("回调参数为："+JSON.toJSONString(map));
    PayRequestVo request = new PayRequestVo();
    request.setPay_code(map.get("orderNo"));
    request.setStatus(PayConstants.PAY_REQUEST_STATUS_PAIED);
    String code = payService.paySuccess(request).getRetCode();
    if(!ErrorCode.SuccessRetCode.equals(code)){
      throw new RuntimeException();
    }
    String updateOrder = payService.updateOrderPaySuccess(request).getRetCode();
    if(!ErrorCode.SuccessRetCode.equals(updateOrder)){
      throw new RuntimeException();
    }
    
    
    return BaseResult.success();
  }
  
  public BaseResult yjfNotifyLog(Map<String,String> map){
    YjfNotifyLogVo log = new YjfNotifyLogVo();
    log.setId(map.get("id"));
    log.setProtocol(map.get("protocol"));
    log.setService(map.get("service"));
    log.setVersion(map.get("version"));
    log.setSign_type(map.get("sign_type"));
    log.setOrderNo(map.get("orderNo"));
    log.setMerchOrderNo(map.get("merchOrderNo"));
    log.setSignType(map.get("signType"));
    log.setSign(map.get("sign"));
    log.setResultCode(map.get("resultCode"));
    log.setResultMessage(map.get("resultMessage"));
    log.setSuccess(map.get("success"));
    log.setNotifyTime(map.get("notifyTime"));
    log.setTradeNo(map.get("tradeNo"));
    log.setTradeAmount(map.get("tradeAmount"));
    log.setMerchantChargeAmount(map.get("merchantChargeAmount"));
    log.setTradeAmountIn(map.get("tradeAmountIn"));
    log.setCommandPayStatus(map.get("commandPayStatus"));
    log.setPayMethod(map.get("payMethod"));
    log.setAddtime(map.get("addtime"));
    log.setAdduser(map.get("adduser"));
    
    yjfDao.yjfLog(log);
    return BaseResult.success();
  }
}
